package com.hmdp.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hmdp.dto.Result;
import com.hmdp.entity.ShopType;
import com.hmdp.mapper.ShopTypeMapper;
import com.hmdp.service.IShopTypeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 虎哥
 * @since 2021-12-22
 */
@Service
public class ShopTypeServiceImpl extends ServiceImpl<ShopTypeMapper, ShopType> implements IShopTypeService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 查询所有商铺类型
     */
    @Override
    public Result queryList() {

        // 获取java操作redis的list操作
        ListOperations<String, String> listOps = stringRedisTemplate.opsForList();
        String key = "cache:shopType";

        // 1.从redis中查询
        ObjectMapper redisObjectMapper = new ObjectMapper();
        List<ShopType> redisShopTypes = listOps.range(key, 0, -1).stream().map(shopType -> {
            try {
                return redisObjectMapper.readValue(shopType, ShopType.class);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }).collect(Collectors.toList());

        // 2.存在就直接返回
        if (!redisShopTypes.isEmpty()) {
            return Result.ok(redisShopTypes);
        }

        // 3.不存在就查询数据库
        List<ShopType> shopTypes = list();

        // 4.数据库中不存在就返回错误
        if (shopTypes == null || shopTypes.isEmpty()) {
            return Result.fail("店铺不存在");
        }

        // 5.数据库中存在就写入redis并返回
        ObjectMapper objectMapper = new ObjectMapper(); // 用于JSON转换
        // 将对象列表转为JSON字符串列表
        List<String> jsonList = shopTypes.stream()
                .map(shopType -> {
                    try {
                        return objectMapper.writeValueAsString(shopType);
                    } catch (JsonProcessingException e) {
                        throw new RuntimeException("JSON序列化失败", e);
                    }
                }).collect(Collectors.toList());

        // 存入Redis
        stringRedisTemplate.opsForList().rightPushAll(key, jsonList);

        return Result.ok(shopTypes);
    }
}
